#include "fpga_subs.h"
#include "ui_fpga_subs.h"
#include <QFile>
#include <QFileInfo>
#include <QDebug>
#include <QTableWidgetItem>
#include <QHeaderView>
fpga_subs::fpga_subs(QWidget *parent, int dev_numb, QString dev_name) :
    QWidget(parent),
    ui(new Ui::fpga_subs)
{
    ui->setupUi(this);
    // =====================================================
    // add download table
    // --------------------------------------------------
    // table create
    table = new QTableWidget(row,column+1,this);
    ui->ui_table_layout->addWidget(table);
    table->resize(900,350);
    connect(table,&QTableWidget::cellClicked,this,&fpga_subs::on_ui_table_cellClicked);
    // --------------------------------------------
    // table auto size
    table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
//    table->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    table->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
    table->resizeColumnsToContents();
    table->resizeRowsToContents();
    // --------------------------------------------
    // table head data
    QStringList head_lab;
    head_lab << "0x0000" << "0x0001" << "0x0002" << "0x0003" << "note";
    table->setHorizontalHeaderLabels(head_lab);
    QStringList column_lab;

    for(int i = 0; i < row * column; i=i+4)
    {
        column_lab << QString::number(i);
        table->setVerticalHeaderLabels(column_lab);
    }
    // =====================================================
    // add state table
    table_state = new QTableWidget(row,column+1,this);
    ui->ui_table_read->addWidget(table_state);
    table_state->resize(900,350);
    connect(table_state,&QTableWidget::cellClicked,this,&fpga_subs::on_ui_table_cellClicked);
    ui->ui_update_state->setValue(0); //monitor state update
    // --------------------------------------------
    // table_state auto size
    table_state->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
//    table->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    table_state->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
    table_state->resizeColumnsToContents();
    table_state->resizeRowsToContents();
    // --------------------------------------------
    // table_state head data
    QStringList head_lab_state;
    head_lab_state << "0x0000" << "0x0001" << "0x0002" << "0x0003" << "note";
    table_state->setHorizontalHeaderLabels(head_lab_state);
    QStringList column_lab_state;

    for(int i = 0; i < row * column; i=i+4)
    {
        column_lab_state << QString::number(i);
        table->setVerticalHeaderLabels(column_lab_state);
    }
    cur_row = 1;
    cur_column = 1;
    // --------------------------------------------
    // add dev detect code
    switch(dev_numb)
    {
    case(3): //xc7s
        DEV_CODE_FPGA_SET        = CODE_FPGA_SET      ;
        DEV_CODE_UART_PL         = CODE_UART_PL       ;
        DEV_CODE_UART_PL_CAMERA  = CODE_UART_PL_CAMERA;
        DEV_CODE_FPGA_STATE      = CODE_FPGA_STATE    ;
        break;
    case(2):
        DEV_CODE_FPGA_SET        = CODE2_FPGA_SET      ;
        DEV_CODE_UART_PL         = CODE2_UART_PL       ;
        DEV_CODE_UART_PL_CAMERA  = CODE2_UART_PL_CAMERA;
        DEV_CODE_FPGA_STATE      = CODE2_FPGA_STATE    ;
        break;
    }

    // --------------------------------------------
    // win set
    dev_numb_tmp = dev_numb;
    dev_name_temp = dev_name;
    F_SETWIN
}

fpga_subs::~fpga_subs()
{
    delete ui;
}

void fpga_subs::update_file_path(QList<QString> p_list)
{
    p_fpga_file = p_list[P_FPGA_FILE]; //path update
    ui->tabWidget->setCurrentIndex(0);
    on_ui_rd_param_clicked(); //update chart
    on_ui_reset_state_clicked(); //update state
}


void fpga_subs::on_ui_rd_param_clicked()
{
    QString pns_ini;
    pns_ini = p_fpga_file + "fpga_ini" + QString::number(dev_numb_tmp) +".dat";
    QFile f(pns_ini);
    QFileInfo fi(pns_ini);

    qDebug() << pns_ini;
    if(!fi.exists())
    {
        QString info = "no file " + pns_ini + " to read";
        emit info_trig(0,DEV_CODE_FPGA_SET,"error",info);
        return;
    }
    f.open(QIODevice::ReadOnly | QIODevice::Text);
    l_fpga_set.clear();
    for(int j = 0; j < row * column; j++)
    {
        l_fpga_set.append("0");
    }
    int i = 0;
    while(!f.atEnd() && i < row * column)
    {
        QByteArray b_line =  f.readLine();
        QString s_line(b_line);
        s_line.remove("\n");
        l_fpga_set.replace(i,s_line);
        i ++;
    }
    f.close();
    //qDebug() << l_fpga_set;

    for(int i = 0; i <row;i++)
    {
        for(int j = 0; j < column; j++)
        {
            //table->item(i,j)->setText(l_fpga_set[i*4+j]);
             QTableWidgetItem *item = new QTableWidgetItem;
             item->setText(l_fpga_set[i*column+j]);
             table->setItem(i,j,item);
             //delete item;
        }
    }
    // --------------------------------------------
    // add note
    //new file
    pns_ini = p_fpga_file + "fpga_info" + QString::number(dev_numb_tmp) +".txt";
    QFile fid(pns_ini);
    QFileInfo fid_if(pns_ini);

    qDebug() << pns_ini;
    if(!fid_if.exists())
    {
        QString info = "no file " + pns_ini + " to read";
        emit info_trig(0,DEV_CODE_FPGA_SET,"error",info);
        return;
    }
    fid.open(QIODevice::ReadOnly | QIODevice::Text);
    l_fpga_info.clear();
    for(int j = 0; j < row; j++)
    {
        l_fpga_info.append(" ");
    }
    i = 0;
    while(!fid.atEnd() && i < row)
    {
        QByteArray b_line = fid.readLine();
        QString s_line(b_line);
        s_line.remove("\n");
        l_fpga_info.replace(i,s_line);
        i ++;
    }
    fid.close();
    for(int i = 0; i <row;i++)
    {
        //table->item(i,j)->setText(l_fpga_set[i*4+j]);
        QTableWidgetItem *item = new QTableWidgetItem;
        item->setText(l_fpga_info[i]);
        table->setItem(i,column,item);
        //delete item;
    }
}
void fpga_subs::on_ui_wr_param_clicked()
{
    QRegExp regx("[A-Fa-f0-9]{1,8}");
    l_fpga_set.clear();
    for(int i = 0; i <row;i++)
    {
        for(int j = 0; j < column; j++)
        {
            //table->item(i,j)->setText(l_fpga_set[i*4+j]);
             QTableWidgetItem *item_rd = new QTableWidgetItem;
             item_rd = table->item(i,j);
             if(item_rd == NULL)
             {
                l_fpga_set.append("00000000");
             }
             else if(regx.exactMatch(item_rd->text()))
             {
                QString str = QString("%1").arg(item_rd->text(), 8, QLatin1Char('0'));
                l_fpga_set.append(str);
             }
             else //data not match
             {
                l_fpga_set.append("00000000");
             }
        }
    }
    //write file
    QString pns_ini;
    pns_ini = p_fpga_file + "fpga_ini" + QString::number(dev_numb_tmp) +".dat";
    QFile f(pns_ini);
    f.open(QIODevice::WriteOnly | QIODevice::Text);
    QTextStream f_out(&f);
    f.seek(0);
    for(int i = 0; i < row * column; i++)
    {
        f_out << l_fpga_set[i] << "\n";
    }
    f.close();
    on_ui_rd_param_clicked();

    // --------------------------------------------
    // send signal to UDP to tran to ARM
    emit udp_trig(pns_ini,DEV_CODE_FPGA_SET);
    emit uart_trig(pns_ini,DEV_CODE_UART_PL);
}


void fpga_subs::on_ui_close_clicked()
{
    close();
}

void fpga_subs::on_ui_table_cellClicked(int row,int column)
{
    bool ok;
    quint32 hex = 0x0000;
    if(ui->tabWidget->currentIndex() == 0)
    {
        hex =  table->item(row,column)->text().toInt(&ok,16);
    }
    else if(ui->tabWidget->currentIndex() == 1)
    {
        hex =  table_state->item(row,column)->text().toInt(&ok,16);
        //add still site
        cur_column = column;
        cur_row = row;
        if(state_update_still_flg)
        {
            emit scene_to_wave();
        }
    }
    quint32 dec =  0;
    quint32 bit =  0;
    emit hex_trig(hex,dec,bit);

}


void fpga_subs::on_ui_reset_state_clicked()
{
    QString pns_ini;
    pns_ini = p_fpga_file + "fpga_ini_state" + ".dat";
    QFile f(pns_ini);
    QFileInfo fi(pns_ini);

    qDebug() << pns_ini;
    if(!fi.exists())
    {
        QString info = "no file " + pns_ini + " to read";
        emit info_trig(0,DEV_CODE_FPGA_STATE,"error",info);
        return;
    }
    f.open(QIODevice::ReadOnly | QIODevice::Text);
    l_fpga_state.clear();
    for(int j = 0; j < row * column; j++)
    {
        l_fpga_state.append("0");
    }
    int i = 0;
    while(!f.atEnd() && i < row * column)
    {
        QByteArray b_line =  f.readLine();
        QString s_line(b_line);
        s_line.remove("\n");
        l_fpga_state.replace(i,s_line);
        i ++;
    }
    f.close();
    //qDebug() << l_fpga_set;

    for(int i = 0; i <row;i++)
    {
        for(int j = 0; j < column; j++)
        {
            //table->item(i,j)->setText(l_fpga_set[i*4+j]);
             QTableWidgetItem *item = new QTableWidgetItem;
             item->setText(l_fpga_state[i*column+j]);
             table_state->setItem(i,j,item);
             //delete item;
        }
    }
    // --------------------------------------------
    // add note
    //new file
    QString pns_ini_info = p_fpga_file + "fpga_info_state" + QString::number(dev_numb_tmp) +".txt";
    QFile fid(pns_ini_info);
    QFileInfo fid_if(pns_ini_info);

    qDebug() << pns_ini_info;
    if(!fid_if.exists())
    {
        QString info = "no file " + pns_ini_info + " to read";
        emit info_trig(0,DEV_CODE_FPGA_STATE,"error",info);
        return;
    }
    fid.open(QIODevice::ReadOnly | QIODevice::Text);
    l_fpga_state_info.clear();
    for(int j = 0; j < row; j++)
    {
        l_fpga_state_info.append(" ");
    }
    i = 0;
    while(!fid.atEnd() && i < row)
    {
        QByteArray b_line = fid.readLine();
        QString s_line(b_line);
        s_line.remove("\n");
        l_fpga_state_info.replace(i,s_line);
        i ++;
    }
    fid.close();
    for(int i = 0; i <row;i++)
    {
        //table->item(i,j)->setText(l_fpga_set[i*4+j]);
        QTableWidgetItem *item = new QTableWidgetItem;
        item->setText(l_fpga_state_info[i]);
        table_state->setItem(i,column,item);
        //delete item;
    }
    //close still run
    state_update_still_flg = false;
    emit uart_trig(pns_ini,DEV_CODE_FPGA_STATE);
    //close still info
    QString info = "still state is close";
    emit info_trig(0,DEV_CODE_FPGA_STATE,"info",info);
}

void fpga_subs::update_state_data(QList<quint32> data_state, quint32 numb_cmd)
{
    bool ok;
    QByteArray ba_dev = dev_name_temp.toLocal8Bit();
    QString str_dev = ba_dev.toHex();
    if(str_dev != QString::number(numb_cmd,16)) //check if this board state right
    {
        qDebug() << ba_dev << str_dev << QString::number(numb_cmd,16);
        return;
    }
    for(int i = 0; i < data_state.size() / 4;i++)
    {
        for(int j = 0; j < 4; j = j + 1)
        {
            //table->item(i,j)->setText(l_fpga_set[i*4+j]);
            QTableWidgetItem *item = new QTableWidgetItem;
            item->setText(QString::number(data_state[i*4+j],16)); //show data in hex mode
            table_state->setItem(i,j,item);
            //delete item;
        }
    }
    if(ui->ui_update_state->value() < 100)
    {
        ui->ui_update_state->setValue(ui->ui_update_state->value()+1);
    }
    else
    {
        ui->ui_update_state->setValue(0);
    }
    //add state monitor

    quint32 hex =  table_state->item(cur_row,cur_column)->text().toInt(&ok,16);
    qDebug() << cur_row << cur_column;
    emit hex_trig(hex,dev_numb_tmp,MD_WAVE_SHOW);
    //add still mode
    if(state_update_still_flg)
    {
        QString pns_ini = p_fpga_file + "fpga_info_state" + QString::number(dev_numb_tmp) +".txt";
        emit uart_trig(pns_ini,DEV_CODE_FPGA_STATE);
    }
}


void fpga_subs::on_ui_update_still_clicked()
{
    QString pns_ini = p_fpga_file + "fpga_info_state" + QString::number(dev_numb_tmp) +".txt";
    state_update_still_flg = true;
    emit uart_trig(pns_ini,DEV_CODE_FPGA_STATE);
    QString info = "still state is open";
    emit info_trig(0,DEV_CODE_FPGA_STATE,"info",info);
}

